package cn.itcast.zt.utils;

import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;

import java.io.Serializable;

/**
 * 注意：业务个性化异常枚举需要有busiCode和busiMsg定义code码和描述信息，BaseBusiCodeEnum基础枚举（约定）只是使用在响应成功||失败，并且非使用业务异常的场景，固化在代码中
 * @author zhangtian
 * create by zhangtian3 on 2018/10/8
 */
// 保证序列化json的时候,如果是null的对象,key也会消
public class ServerResponse<T> implements Serializable {
    /**
     * 响应码
     */
    private String code;
    /**
     * 返回业务码
     */
    private String busiCode ;
    /**
     * 业务信息
     */
    private String message;
    /**
     * 响应体数据包装
     */
    private T data;

    private ServerResponse(String code, String busiCode) {
        this.code = code;
        this.busiCode = busiCode ;
    }

    private ServerResponse(String code, String busiCode, T data) {
        this.code = code;
        this.busiCode = busiCode ;
        this.data = data;
    }

    private ServerResponse(String code, String busiCode, String message, T data) {
        this.code = code;
        this.busiCode = busiCode ;
        this.message = message;
        this.data = data;
    }

    private ServerResponse(String code, String busiCode, String message) {
        this.code = code;
        this.busiCode = busiCode ;
        this.message = message;
    }

    public static <T> ServerResponse<T> createBySuccess() {
        return new ServerResponse<T>(SysCodeEnum.Success.getCode(), BaseBusiCodeEnum.B_Success.getBusiCode(), SysCodeEnum.Success.getMsg());
    }

    public static <T> ServerResponse<T> createBySuccessMessage(String msg) {
        return new ServerResponse<T>(SysCodeEnum.Success.getCode(), BaseBusiCodeEnum.B_Success.getBusiCode(), msg);
    }

    public static <T> ServerResponse<T> createBySuccess(T data) {
        return new ServerResponse<T>(SysCodeEnum.Success.getCode(), BaseBusiCodeEnum.B_Success.getBusiCode(), data);
    }

    public static <T> ServerResponse<T> createBySuccess(String msg, T data) {
        return new ServerResponse<T>(SysCodeEnum.Success.getCode(), BaseBusiCodeEnum.B_Success.getBusiCode(), msg, data);
    }

    // --------------------------------- 以上是处理成功的默认success -------------------------------

    public static <T> ServerResponse<T> createCodeMessage(String code, String busiCode, String msg, T data) {
        return new ServerResponse<T>(code, busiCode, msg, data);
    }

    /**
     * 业务码异常时的输出，不含data
     * @param baseBusiCodeEnum
     * @return
     * @param <T>
     */
    public static <T> ServerResponse<T> createByBusiError(Enum baseBusiCodeEnum) {
        // 通过反射使枚举参数通用化
        /*try {
            Class<? extends Enum> clazz = baseBusiCodeEnum.getClass();
            Field busiCodeField = clazz.getDeclaredField("busiCode");
            Field busiMsgField = clazz.getDeclaredField("busiMsg");

            busiCodeField.setAccessible(true);
            busiMsgField.setAccessible(true);
            return new ServerResponse<T>(SysCodeEnum.Success.getCode(), (String) busiCodeField.get(baseBusiCodeEnum), (String) busiMsgField.get(baseBusiCodeEnum));
        }catch (Exception ex) {
            ex.printStackTrace();
        }*/

        try {
            String busiCode = (String) ReflectUtil.getFieldValue(baseBusiCodeEnum, ReflectUtil.getField(baseBusiCodeEnum.getClass(), "busiCode")) ;
            String busiMsg = (String) ReflectUtil.getFieldValue(baseBusiCodeEnum, ReflectUtil.getField(baseBusiCodeEnum.getClass(), "busiMsg")) ;
            return new ServerResponse<T>(SysCodeEnum.Success.getCode(), busiCode, busiMsg);
        }catch (Exception ex) {
            ex.printStackTrace();
        }

        return null ;
    }

    /**
     * 业务码异常时的输出，含data
     * @param baseBusiCodeEnum
     * @param data
     * @return
     * @param <T>
     */
    public static <T> ServerResponse<T> createByBusiError(Enum baseBusiCodeEnum, T data) {
        // 通过反射使枚举参数通用化
        /*try {
            Class<? extends Enum> clazz = baseBusiCodeEnum.getClass();
            Field busiCodeField = clazz.getDeclaredField("busiCode");
            Field busiMsgField = clazz.getDeclaredField("busiMsg");

            busiCodeField.setAccessible(true);
            busiMsgField.setAccessible(true);
            return new ServerResponse<T>(SysCodeEnum.Success.getCode(), (String) busiCodeField.get(baseBusiCodeEnum), (String) busiMsgField.get(baseBusiCodeEnum), data);
        }catch (Exception ex) {
            ex.printStackTrace();
        }*/

        try {
            String busiCode = (String) ReflectUtil.getFieldValue(baseBusiCodeEnum, ReflectUtil.getField(baseBusiCodeEnum.getClass(), "busiCode")) ;
            String busiMsg = (String) ReflectUtil.getFieldValue(baseBusiCodeEnum, ReflectUtil.getField(baseBusiCodeEnum.getClass(), "busiMsg")) ;
            return new ServerResponse<T>(SysCodeEnum.Success.getCode(), busiCode, busiMsg, data);
        }catch (Exception ex) {
            ex.printStackTrace();
        }

        return null ;
    }

    // 使之不在json序列化结果当中
    public boolean isSuccess() {
        return StrUtil.equals(this.code, SysCodeEnum.Success.getCode());
    }

    public String getCode() {
        return code;
    }

    public String getBusiCode() {
        return busiCode;
    }

    public T getData() {
        return data;
    }

    public String getMessage() {
        return message;
    }
}
